package com.edu.nchu.study.service.impl;

import com.edu.nchu.study.model.DataSet;
import com.edu.nchu.study.service.DataSetSupportService;
import com.edu.nchu.study.utils.BootConstants;
import com.edu.nchu.study.utils.DataSetHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Service
public class DataSetSupportServiceImpl extends AbstractRoutingDataSource
        implements DataSetSupportService, ApplicationContextAware {

    private final static Map<Object, Object> DS_MAP = new ConcurrentHashMap<>();
    //@Value("classpath:/init_script/init_table.sql")
    //private Resource resource;

    private ApplicationContext applicationContext;

    @Autowired
    public DataSetSupportServiceImpl(DataSource primaryDataSource) {
        super.setDefaultTargetDataSource(primaryDataSource);
        super.setTargetDataSources(DS_MAP);
    }

    @Override
    protected Object determineCurrentLookupKey() {
        return DataSetHolder.get();
    }

    @Override
    public void setDefaultTargetDataSource(Object defaultTargetDataSource) {
        super.setDefaultTargetDataSource(defaultTargetDataSource);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void createDataSource(DataSet dataSet) {
        createDataSource(dataSet.getCode());
    }

    @Override
    public void createDataSource(String code) {
        DataSource dataSource = DataSourceBuilder.create().driverClassName(BootConstants.MYSQL_DRIVER_CLASS)
                .password(BootConstants.MYSQL_DATABASE_PASSWORD)
                .username(BootConstants.MYSQL_DATABASE_USERNAME)
                .url(String.format(BootConstants.MYSQL_DATABASE_URL_FORMAT, code))
                .build();
        ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
        try {
            Resource[] resources = applicationContext.getResources("classpath*:/init_script/init_*.sql");
            populator.addScripts(resources);
        } catch (Exception e) {
            log.error("get init resources error", e);
        }
        DatabasePopulatorUtils.execute(populator, dataSource);
        DS_MAP.put(code, dataSource);
    }
}
